/**
 * 
 */
package com.jonosoft.photocast.viewer.web.client;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;

import com.jonosoft.photocast.viewer.web.client.photocast.Photocast;
import com.jonosoft.photocast.viewer.web.client.photocast.PhotocastItem;
import com.jonosoft.photocast.viewer.web.client.ui.LibraryImage;

/**
 * TODO Add description ImageSet
 * (com.jonosoft.photocast.viewer.web.client.ImageSet)
 * 
 * @author jon
 * 
 */
public class ImageCollection extends ArrayList {
	
	private static final String ILLEGAL_ARGUMENT_EXCEPTION = "Argument must be of type LibraryImage.";
	
	public static final class SortableFields {
		public static final SortableFields TITLE = new SortableFields();
		public static final SortableFields PHOTO_DATE = new SortableFields();
		public static final SortableFields PUBLISH_DATE = new SortableFields();
	}
	
	public static final class SortOrder {
		public static final SortOrder ASCENDING = new SortOrder();
		public static final SortOrder DESCENDING = new SortOrder();
	}
	
	private SortableFields sortByField = null;
	private SortOrder sortOrder = null;
	private final LibraryImageComparator comparator = new LibraryImageComparator();
	
	private String title = null;
	private String url = null;

	public static ImageCollection createFromPhotocast(Photocast photocast) {
		ImageCollection imageCollection = new ImageCollection();

		imageCollection.setTitle(photocast.getTitle());
		imageCollection.setUrl(photocast.getPhotocastURL());
		
		Iterator i = photocast.getPhotocastItems().iterator();
		
		while (i.hasNext())
			imageCollection.add(LibraryImage
			        .createFromPhotocastItem((PhotocastItem) i.next()));

		return imageCollection;
	}
	
	public ImageCollection() {
		setSortByField(SortableFields.PHOTO_DATE);
		setSortOrder(SortOrder.DESCENDING);
	}
	
	public ImageCollection(ImageCollection libraryImageCollection) {
		this();
		addAll(libraryImageCollection);
		setTitle(libraryImageCollection.getTitle());
		setUrl(libraryImageCollection.getUrl());
	}
	
	public Object clone() {
	    return new ImageCollection(this);
    }
	
	public String getTitle() {
		return this.title;
	}
	
	public String getUrl() {
		return this.url;
	}

	public void setTitle(String title) {
		this.title = title;
	}
	
	public void setUrl(String url) {
		this.url = url;
	}
	
	public boolean add(LibraryImage libraryImage) {
		if (libraryImage instanceof LibraryImage) {
			return super.add((LibraryImage) libraryImage);
		} else
			throw new IllegalArgumentException(ILLEGAL_ARGUMENT_EXCEPTION);
	}
	
	public boolean addAll(Collection libraryImageCollection) {
		Iterator collectionIterator = libraryImageCollection.iterator();
		
		while (collectionIterator.hasNext())
			if (!(collectionIterator.next() instanceof LibraryImage))
				throw new IllegalArgumentException(ILLEGAL_ARGUMENT_EXCEPTION);

		return super.addAll(libraryImageCollection);
	}
	
	private void setSortByField(SortableFields field) {
		this.sortByField = field;
		comparator.setSortByField(sortByField);
	}
	
	private void setSortOrder(SortOrder so) {
		this.sortOrder  = so;
		comparator.setSortOrder(so);
	}
	
	private void sort() {
		Collections.sort(this, comparator);
	}
	
	public void sort(SortableFields sortByField, SortOrder sortOrder) {
		setSortByField(sortByField);
		setSortOrder(sortOrder);
		sort();
	}
	
	public void sort(SortableFields sortByField) {
		sort(sortByField, sortOrder);
	}
	
	public void sort(SortOrder sortOrder) {
		sort(sortByField, sortOrder);
	}

	private class LibraryImageComparator implements Comparator {
    	private SortableFields sortByField = null;
		private SortOrder sortOrder = null;
    	
        public LibraryImageComparator() {
        	setSortByField(SortableFields.PHOTO_DATE);
        }
    	
        public void setSortByField(SortableFields sortByField) {
        	this.sortByField = sortByField;
        }
        
        public void setSortOrder(SortOrder so) {
        	this.sortOrder = so;
        }

		/**
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(Object e0, Object e1) {
        	int val = 0;
        	LibraryImage i0 = (LibraryImage) e0;
        	LibraryImage i1 = (LibraryImage) e1;
        	if (sortByField.equals(SortableFields.TITLE))
        		val = i0.getTitle().toLowerCase().compareTo(i1.getTitle().toLowerCase());
			else if (sortByField.equals(SortableFields.PHOTO_DATE))
				val = i0.getPhotoDate().compareTo(i1.getPhotoDate());
			else if (sortByField.equals(SortableFields.PUBLISH_DATE))
				val = i0.getPublishDate().compareTo(i1.getPublishDate());
        	else
        		return 0;
        	
        	if (val == 0 && i0.getGuid().equals(i1.getGuid()))
        		val = 1;
        	
        	if (this.sortOrder.equals(SortOrder.DESCENDING))
        		val *= -1;
        	
        	return val;
        }
    }

}
